<!DOCTYPE html>

<html>

<head>
  <title>可视化小元素</title>
  <script type="text/javascript" src="../three/build/three.js"></script>
  <script type="text/javascript" src="../three/examples/js/controls/OrbitControls.js"></script>
  <script type="text/javascript" src="../three/examples/js/renderers/CSS2DRenderer.js"></script>
  <script type="text/javascript" src="../three/examples/js/libs/stats.min.js"></script>
  <!-- EffectComposer要先于其他后期处理文件引入，否则其他文件无法正确引入 -->
  <script type="text/javascript" src="../three/examples/js/postprocessing/EffectComposer.js"></script>
  <script type="text/javascript" src="../three/examples/js/postprocessing/RenderPass.js"></script>
  <script type="text/javascript" src="../three/examples/js/postprocessing/ShaderPass.js"></script>
  <script type="text/javascript" src="../three/examples/js/postprocessing/UnrealBloomPass.js"></script>
  <script type="text/javascript" src="../three/examples/js/shaders/LuminosityHighPassShader.js"></script>
  <script type="text/javascript" src="../three/examples/js/shaders/CopyShader.js"></script>
  <script type="text/javascript" src="./js/components.js"></script>

  <style>
    body {
      margin: 0;
      overflow: hidden;
    }

    .label {
      color: #FFF;
      font-family: sans-serif;
      font-size: 50px;
      padding: 2px;
      background: rgba(0, 0, 0, .6);
    }
  </style>
</head>

<body>

  <div id="Stats-output"></div>
  <div id="WebGL-output"></div>

  <script type="text/javascript">
    var scene, camera, renderer, labelRenderer, labelDiv, stats, controls, clock;
    var composer, unrealBloomPass;

    var circlePercentComponent = null;
    var currentNum = 20;

    function initScene() {
      scene = new THREE.Scene();
      //用一张图加载为纹理作为场景背景
      //scene.background = new THREE.TextureLoader().load("../assets/textures/starry-deep-outer-space-galaxy.jpg");
    }

    function initCamera() {
      camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
      camera.position.set(0, 0, 50);
      camera.lookAt(new THREE.Vector3(0, 0, 0));
    }

    function initLight() {
      //添加环境光
      const ambientLight = new THREE.AmbientLight(0x0c0c0c);
      scene.add(ambientLight);

      const directionalLight = new THREE.DirectionalLight('#fff')
      directionalLight.position.set(20, 30, 50)
      scene.add(directionalLight)

      //添加聚光灯
      const spotLight = new THREE.SpotLight(0xffffff);
      spotLight.position.set(-40, 60, -10);
      spotLight.castShadow = true;
      scene.add(spotLight);
    }

    function initModel() {
      initPlane();

      circlePercentComponent = new CirclePercent()
      scene.add(circlePercentComponent)

    }



    //创建底面
    function initPlane() {
      const planeGeometry = new THREE.PlaneGeometry(1, 1, 1, 1); //创建一个平面几何对象

      //材质
      const planeMaterial = new THREE.MeshLambertMaterial({
        transparent: true,
        opacity: 0.0
      });
      const plane = new THREE.Mesh(planeGeometry, planeMaterial);

      //平面添加到场景中
      scene.add(plane);

      //添加label
      labelDiv = document.createElement('div');
      labelDiv.className = 'label';
      //labelDiv.textContent = currentNum+' %';
      labelDiv.style.background = 'none';
      const label = new THREE.CSS2DObject(labelDiv);
      label.position.set(0, 0, -1);
      plane.add(label);
    }

    //初始化渲染器
    function initRender() {
      renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
      });
      renderer.setClearColor(0x111111, 1); //设置背景颜色
      renderer.setSize(window.innerWidth, window.innerHeight);
      //renderer.shadowMap.enabled = true; //显示阴影
      document.getElementById("WebGL-output").appendChild(renderer.domElement);
      //创建CSS2DRenderer渲染器
      labelRenderer = new THREE.CSS2DRenderer();
      labelRenderer.setSize(window.innerWidth, window.innerHeight);
      labelRenderer.domElement.style.position = 'absolute';
      labelRenderer.domElement.style.top = '0px';
      document.getElementById("WebGL-output").appendChild(labelRenderer.domElement);
    }
    //初始化轨道控制器
    function initControls() {
      clock = new THREE.Clock(); //创建THREE.Clock对象，用于计算上次调用经过的时间
      controls = new THREE.OrbitControls(camera, renderer.domElement);
      //controls.autoRotate = true; //是否自动旋转
    }


    //性能监控
    function initStats() {
      stats = new Stats();
      stats.setMode(0); //0: fps, 1: ms
      document.getElementById("Stats-output").appendChild(stats.domElement);
    }


    function render() {
      const delta = clock.getDelta(); //获取自上次调用的时间差
      controls.update(delta); //控制器更新

      circlePercentComponent.updatePercent(currentNum)
      labelDiv.textContent = currentNum + ' %';

      stats.update();
      requestAnimationFrame(render);
      labelRenderer.render(scene, camera);
      renderer.render(scene, camera);
      if (composer) {
        composer.render();
      }
    }

    function initCustomShader() {


      //使用场景和相机创建RenderPass通道
      const renderPass = new THREE.RenderPass(scene, camera)


      /****UnrealBloomPass泛光通道构造函数参数****/
      /* 
      resolution：表示泛光所覆盖的场景大小，是Vector2类型的向量
      strength：表示泛光的强度，值越大明亮的区域越亮，较暗区域变亮的范围越广
      radius：表示泛光散发的半径
      threshold：表示产生泛光的光照强度阈值，如果照在物体上的光照强度大于该值就会产生泛光 
      */

      //创建UnrealBloomPass泛光通道
      unrealBloomPass = new THREE.UnrealBloomPass(
        new THREE.Vector2(256, 256),
        0.5,
        0.8,
        0.12
      )
      unrealBloomPass.renderToScreen = true

      const effectCopy = new THREE.ShaderPass(THREE.CopyShader);

      effectCopy.renderToScreen = true;

      //创建效果组合器
      composer = new THREE.EffectComposer(renderer)

      //将创建的通道添加到EffectComposer(效果组合器)对象中
      composer.addPass(renderPass)
      composer.addPass(unrealBloomPass)
      composer.addPass(effectCopy)

    }

    //页面初始化
    function init() {
      initScene();
      initCamera();
      initLight();
      initModel();
      initRender();
      initStats();
      initControls();
      initCustomShader();
      render();
      setInterval(() => {
        currentNum = parseInt(Math.random() * 100)
      }, 1000)
    }

    window.onload = init;
  </script>
</body>

</html>